﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PACKETPARSERMAX20.CONSOLE
{


    public static class ModbParserv1
    {
        public class SQLInfo
        {
            public string name;
            public string signiture;
            public string regex;

        }


        public static SortedList<string, SQLInfo> GetSQLInfoList()
        {
            SortedList<string, SQLInfo> SQLInfoList = new SortedList<string, SQLInfo>();

            //SQLInfoList.Add("vendor-item_template", new SQLInfo() { name = "item_template", signiture = "UPDATE `item_template`", regex = ".*SET (.*);" });
            //SQLInfoList.Add("vendor-npc_vendor", new SQLInfo() { name = "npc_vendor", signiture = "DELETE FROM `npc_vendor` WHERE `entry` = '32294';", regex = "" });
            //SQLInfoList.Add("vehicle-creature_template_addon", new SQLInfo() { name = "creature_template_addon", signiture = "INSERT IGNORE INTO `creature_template_addon`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("vehicle-npc_spellclick_spells", new SQLInfo() { name = "npc_spellclick_spells", signiture = "INSERT IGNORE INTO `npc_spellclick_spells`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("vehicle-vehicle_data", new SQLInfo() { name = "vehicle_data", signiture = "INSERT IGNORE INTO `vehicle_data` (`entry`) VALUES (106);", regex = "" });
            //SQLInfoList.Add("updates-creature", new SQLInfo() { name = "creature", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("updates-creature_(1)", new SQLInfo() { name = "creature_(1)", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("updates-creature_(2)", new SQLInfo() { name = "creature_(2)", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("updates-creature_addon", new SQLInfo() { name = "creature_addon", signiture = "REPLACE INTO `creature_addon`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-creature_equip_template", new SQLInfo() { name = "creature_equip_template", signiture = "REPLACE INTO `creature_equip`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-creature_model_info", new SQLInfo() { name = "creature_model_info", signiture = "UPDATE `creature_model_info`", regex = ".*SET (.*);" });
            SQLInfoList.Add("updates-creature_template", new SQLInfo() { name = "creature_template", signiture = "UPDATE `creature_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("updates-creature_template_(1)", new SQLInfo() { name = "creature_template_(1)", signiture = "UPDATE `creature_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("updates-creature_template_(2)", new SQLInfo() { name = "creature_template_(2)", signiture = "UPDATE `creature_template`", regex = ".*SET (.*);" });
            //SQLInfoList.Add("updates-gameobject", new SQLInfo() { name = "gameobject", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("updates-gameobject_(1)", new SQLInfo() { name = "gameobject_(1)", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("updates-gameobject_(2)", new SQLInfo() { name = "gameobject_(2)", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-gameobject_template", new SQLInfo() { name = "gameobject_template", signiture = "UPDATE `gameobject_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("trainer-creature_template", new SQLInfo() { name = "creature_template", signiture = "UPDATE `creature_template`", regex = ".*SET (.*);" });
            //SQLInfoList.Add("trainer-npc_trainer", new SQLInfo() { name = "npc_trainer", signiture = "DELETE FROM `npc_trainer` WHERE `entry` = '28703';", regex = "" });
            SQLInfoList.Add("spells-creature_spell", new SQLInfo() { name = "creature_spell", signiture = "REPLACE  INTO `creature_spells`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("spells-playercreateinfo_spell", new SQLInfo() { name = "playercreateinfo_spell", signiture = "INSERT INTO `playercreateinfo_spell`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("quests-creature_quests", new SQLInfo() { name = "creature_quests", signiture = "INSERT IGNORE INTO `creature_questrelation`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("quests-quest_template_new", new SQLInfo() { name = "quest_template_new", signiture = "INSERT IGNORE INTO `quest_template`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("quests-quest_template_up", new SQLInfo() { name = "quest_template_up", signiture = "UPDATE `quest_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("others-creature_chat", new SQLInfo() { name = "creature_chat", signiture = "INSERT IGNORE INTO `creature_chat`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-gossip_menu", new SQLInfo() { name = "gossip_menu", signiture = "INSERT IGNORE INTO `gossip_menu`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-gossip_menu_text", new SQLInfo() { name = "gossip_menu_text", signiture = "INSERT IGNORE INTO `gossip_menu_text`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-npc_gossip", new SQLInfo() { name = "npc_gossip", signiture = "INSERT IGNORE INTO `npc_gossip`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-npc_text_new", new SQLInfo() { name = "npc_text_new", signiture = "INSERT IGNORE INTO `npc_text`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-npc_text_up", new SQLInfo() { name = "npc_text_up", signiture = "UPDATE `npc_text`", regex = ".*SET (.*);" });
            SQLInfoList.Add("others-page_text_new", new SQLInfo() { name = "page_text_new", signiture = "INSERT IGNORE  INTO `page_text`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("others-page_text_up", new SQLInfo() { name = "page_text_up", signiture = "UPDATE `page_text`", regex = ".*SET (.*);" });
            SQLInfoList.Add("others-point_of_interest", new SQLInfo() { name = "point_of_interest", signiture = "INSERT IGNORE INTO `points_of_interest`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-creature_loot", new SQLInfo() { name = "creature_loot", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-creature_loot_(1)", new SQLInfo() { name = "creature_loot_(1)", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-creature_loot_(2)", new SQLInfo() { name = "creature_loot_(2)", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-disenchant_loot", new SQLInfo() { name = "disenchant_loot", signiture = "INSERT IGNORE INTO `disenchant_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-fishing_loot", new SQLInfo() { name = "fishing_loot", signiture = "INSERT IGNORE INTO `fishing_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-gameobject_loot", new SQLInfo() { name = "gameobject_loot", signiture = "INSERT IGNORE INTO `gameobject_loot`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("item_template-item_template_new", new SQLInfo() { name = "item_template_new", signiture = "INSERT IGNORE  INTO `item_template`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("item_template-item_template_up", new SQLInfo() { name = "item_template_up", signiture = "UPDATE `item_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("gameobject_template-gameobject_template_new", new SQLInfo() { name = "gameobject_template_new", signiture = "INSERT IGNORE INTO `gameobject_template`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("gameobject_template-gameobject_template_up", new SQLInfo() { name = "gameobject_template_up", signiture = "UPDATE `gameobject_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("creature_template-creature_template_new", new SQLInfo() { name = "creature_template_new", signiture = "INSERT IGNORE  INTO `creature_template`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("creature_template-creature_template_new_all", new SQLInfo() { name = "creature_template_new_all", signiture = "INSERT IGNORE  INTO `creature_template`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("creature_template-creature_template_up", new SQLInfo() { name = "creature_template_up", signiture = "UPDATE `creature_template`", regex = ".*SET (.*);" });
            SQLInfoList.Add("actions-actions", new SQLInfo() { name = "actions", signiture = "INSERT  INTO `playercreateinfo_action`", regex = ".*\\((.*)\\);" });

            return SQLInfoList;
        }

        public static SortedList<string, SQLInfo> GetSQLInfoList2()
        {
            SortedList<string, SQLInfo> SQLInfoList = new SortedList<string, SQLInfo>();

            //SQLInfoList.Add("vendor-item_template", new SQLInfo() { name = "item_template", signiture = "UPDATE `item_template`", regex = ".*SET (.*);" });
            //SQLInfoList.Add("vendor-npc_vendor", new SQLInfo() { name = "npc_vendor", signiture = "DELETE FROM `npc_vendor` WHERE `entry` = '32294';", regex = "" });
            //SQLInfoList.Add("vehicle-creature_template_addon", new SQLInfo() { name = "creature_template_addon", signiture = "INSERT IGNORE INTO `creature_template_addon`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("vehicle-npc_spellclick_spells", new SQLInfo() { name = "npc_spellclick_spells", signiture = "INSERT IGNORE INTO `npc_spellclick_spells`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("vehicle-vehicle_data", new SQLInfo() { name = "vehicle_data", signiture = "INSERT IGNORE INTO `vehicle_data` (`entry`) VALUES (106);", regex = "" });
            SQLInfoList.Add("updates-creature", new SQLInfo() { name = "creature", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-creature_(1)", new SQLInfo() { name = "creature_(1)", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-creature_(2)", new SQLInfo() { name = "creature_(2)", signiture = "INSERT IGNORE INTO `creature`", regex = ".*\\((.*)\\)\\;" });
                //SQLInfoList.Add("updates-creature_addon", new SQLInfo() { name = "creature_addon", signiture = "REPLACE INTO `creature_addon`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-gameobject", new SQLInfo() { name = "gameobject", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-gameobject_(1)", new SQLInfo() { name = "gameobject_(1)", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            SQLInfoList.Add("updates-gameobject_(2)", new SQLInfo() { name = "gameobject_(2)", signiture = "INSERT IGNORE INTO `gameobject`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("trainer-npc_trainer", new SQLInfo() { name = "npc_trainer", signiture = "DELETE FROM `npc_trainer` WHERE `entry` = '28703';", regex = "" });
            //SQLInfoList.Add("loot-creature_loot", new SQLInfo() { name = "creature_loot", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-creature_loot_(1)", new SQLInfo() { name = "creature_loot_(1)", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-creature_loot_(2)", new SQLInfo() { name = "creature_loot_(2)", signiture = "INSERT IGNORE INTO `creature_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-disenchant_loot", new SQLInfo() { name = "disenchant_loot", signiture = "INSERT IGNORE INTO `disenchant_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-fishing_loot", new SQLInfo() { name = "fishing_loot", signiture = "INSERT IGNORE INTO `fishing_loot`", regex = ".*\\((.*)\\)\\;" });
            //SQLInfoList.Add("loot-gameobject_loot", new SQLInfo() { name = "gameobject_loot", signiture = "INSERT IGNORE INTO `gameobject_loot`", regex = ".*\\((.*)\\)\\;" });

            return SQLInfoList;
        }

        public static void Process(int clientbuild)
        {
            string[] files = System.IO.Directory.GetFiles(@"H:\DATA\SQLITE\dbs\11403\", "*.sqlite", System.IO.SearchOption.AllDirectories);
            string tCommandLine = "";

            tCommandLine = string.Format("\"{0}\"", @"H:\DATA\SQLITE\proxy\Modb_Parser_v3.3.2_v1\db_parser.exe");

            int i = 0;

            foreach (string file in files)
            {
                Common.WritePercent(i, files.Length);
                PACKETPARSERMAX20.CORE.ReaderSniffitzSQLite t = new PACKETPARSERMAX20.CORE.ReaderSniffitzSQLite(file);
                if (t.ClientBuild >= clientbuild)
                {
                    t = null;
                    PACKETPARSERMAX20.Support.Execute(file, tCommandLine);
                    //Console.WriteLine(file);
                }
                else
                {
                    t = null;
                }
                i++;
                Common.WritePercent(i, files.Length);
            }
        }
        //public static void Process(int clientbuild)
        //{
        //    string[] files = System.IO.Directory.GetFiles(@"H:\DATA\SQLITE\dbs\", "*.sqlite", System.IO.SearchOption.AllDirectories);
        //    string tCommandLine = string.Format("\"{0}\"", @"H:\DATA\SQLITE\proxy\Modb_Parser_v3.2.x_rev6\db_parser.exe");

        //    int i = 0;

        //    foreach (string file in files)
        //    {
        //        Common.WritePercent(i, files.Length);
        //        PACKETPARSERMAX20.CORE.ReaderSniffitzSQLite t = new PACKETPARSERMAX20.CORE.ReaderSniffitzSQLite(file);
        //        if (t.ClientBuild <= clientbuild)
        //        {
        //            t = null;
        //            PACKETPARSERMAX20.Support.Execute(file, tCommandLine);
        //            //Console.WriteLine(file);
        //        }
        //        else
        //        {
        //            t = null;
        //        }
        //        i++;
        //        Common.WritePercent(i, files.Length);
        //    }
        //}

        public static void DumpSigs(string dir)
        {
            string[] files = System.IO.Directory.GetFiles(dir, "*.sql", System.IO.SearchOption.AllDirectories);

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("signitures.txt"))
            {
                foreach (string file in files)
                {

                    using (System.IO.StreamReader sr = new System.IO.StreamReader(file))
                    {
                        System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(file));

                        string dirname = info.Name;
                        string name = System.IO.Path.GetFileNameWithoutExtension(file);
                        string sigkey = dirname + "-" + name;

                        sw.WriteLine("SQLInfoList.Add(\"" + sigkey + "\", new SQLInfo() { name = \"" + name + "\", signiture = \"" + sr.ReadLine() + "\", regex = \"\" });");

                        sr.Close();
                    }
                }
                sw.Close();
            }
        }

        public static void FixSQLs(string dir)
        {
            string[] files = System.IO.Directory.GetFiles(dir, "*.sql", System.IO.SearchOption.AllDirectories);

            SortedList<string, SQLInfo> SQLInfoList = GetSQLInfoList2();
            string dest = ".\\sql_new\\";

            if (!System.IO.Directory.Exists(dest)) System.IO.Directory.CreateDirectory(dest);

            foreach (string file in files)
            {
                DateTime start = DateTime.Now;

                System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(file));

                string dirname = info.Name;
                string name = System.IO.Path.GetFileNameWithoutExtension(file);
                string sigkey = dirname + "-" + name;

                //if (name != "point_of_interest") continue;
                if (!SQLInfoList.ContainsKey(sigkey))
                {
                    Console.WriteLine(string.Format("Ignored {0}...", sigkey));
                    continue;
                }

                Console.WriteLine(string.Format("Start Processing {0}...", sigkey));

                SQLInfo sqlinfo = SQLInfoList[sigkey];

                string[] a = sigkey.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);

                string tnewdest = dest + a[0] + "\\";

                if (!System.IO.Directory.Exists(tnewdest)) System.IO.Directory.CreateDirectory(tnewdest);

                tnewdest += a[1] + ".sql";

                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(tnewdest))
                {
                    string part = "";
                    bool skip = false;
                    string line = "";
                    bool verifynext = false;
                    List<string> unique = new List<string>();
                    int ignored = 0;

                    using (System.IO.StreamReader sr = new System.IO.StreamReader(file))
                    {
                        while (!sr.EndOfStream)
                        {
                            Common.WritePercent(sr.BaseStream.Position, sr.BaseStream.Length);

                            if (!skip)
                            {
                                line = sr.ReadLine();
                            }

                            if (line.IndexOf(sqlinfo.signiture) == -1)
                            {

                                part += "\\n" + line.Trim();

                                while (!sr.EndOfStream)
                                {
                                    line = sr.ReadLine();

                                    if (line.IndexOf(sqlinfo.signiture) == -1)
                                    {
                                        part += "\\n" + line.Trim();
                                    }
                                    else
                                        break;
                                }

                                skip = true;
                                verifynext = false;
                            }
                            else
                            {

                                if (verifynext)
                                {
                                    string key = System.Text.RegularExpressions.Regex.Replace(part, sqlinfo.regex, "$1");
                                    if (!unique.Contains(key))
                                    {
                                        unique.Add(key);

                                        if (name == "item_template_new")
                                        {

                                            part = part.Replace("`AllowableRace`='2147483647'", "`AllowableRace`='-1'");
                                            part = part.Replace("`RandomProperty`='-1'", "`RandomProperty`='0'");

                                            for (int i = 1; i < 6; i++)
                                            {
                                                part = part.Replace("`spellid_" + i.ToString() + "` = '-1'", "`spellid_" + i.ToString() + "` = '0'");
                                            }

                                        }

                                        if (part.IndexOf('\0') != -1)
                                        {
                                            sw.WriteLine(part.Replace("\0", ""));
                                        }
                                        else
                                            sw.WriteLine(part);
                                    }
                                    else
                                        ignored++;
                                }

                                part = line;
                                skip = false;
                                verifynext = true;
                            }

                            if (!verifynext)
                            {

                                string key = System.Text.RegularExpressions.Regex.Replace(part, sqlinfo.regex, "$1");
                                if (!unique.Contains(key))
                                {

                                    unique.Add(key);


                                    if (name == "item_template_new")
                                    {

                                        part = part.Replace("`AllowableRace`='2147483647'", "`AllowableRace`='-1'");
                                        part = part.Replace("`RandomProperty`='-1'", "`RandomProperty`='0'");

                                        for (int i = 1; i < 6; i++)
                                        {
                                            part = part.Replace("`spellid_" + i.ToString() + "` = '-1'", "`spellid_" + i.ToString() + "` = '0'");
                                        }

                                    }

                                    if (part.IndexOf('\0') != -1)
                                    {
                                        sw.WriteLine(part.Replace("\0", ""));
                                    }
                                    else
                                        sw.WriteLine(part);
                                }
                                else
                                    ignored++;

                            }


                        }

                        if (verifynext)
                        {
                            string key = System.Text.RegularExpressions.Regex.Replace(part, sqlinfo.regex, "$1");
                            if (!unique.Contains(key))
                            {
                                unique.Add(key);


                                if (part.IndexOf('\0') != -1)
                                {
                                    sw.WriteLine(part.Replace("\0", ""));
                                }
                                else
                                    sw.WriteLine(part);
                            }
                            else
                                ignored++;
                        }
                        sr.Close();
                    }

                    sw.Close();

                    Console.WriteLine(string.Format("Completed Processing {0}... unique: {1}, ignored: {2}, total: {3}, took: {4}", sigkey, unique.Count, ignored, ignored + unique.Count, DateTime.Now - start));
                }
            }
        }
    }
}
